const { prisma } = require('../config/prisma');
const jwt = require('jsonwebtoken');
const axios = require('axios');
const { handleShareReward } = require('./share.controller');

/**
 * 微信登录
 */
const login = async (req, res) => {
  try {
    const { code, phone, inviter_id, scene } = req.body;

    if (!code || !phone) {
      return res.status(400).json({
        code: 400,
        message: '请提供必要的登录信息'
      });
    }

    let openId;
    
    // 测试环境下使用模拟的openid
    if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'production') {
      openId = 'test-openid-' + phone;
      console.log('Using test openId:', openId);
    } else {
      // 调用微信接口获取openid
      try {
        const response = await axios.get('https://api.weixin.qq.com/sns/jscode2session', {
          params: {
            appid: process.env.WECHAT_APP_ID,
            secret: process.env.WECHAT_APP_SECRET,
            js_code: code,
            grant_type: 'authorization_code'
          }
        });

        console.log('WeChat API response:', response.data);

        if (!response.data.openid) {
          return res.status(400).json({
            code: 400,
            message: '微信登录失败'
          });
        }

        openId = response.data.openid;
      } catch (error) {
        console.error('WeChat API error:', error.response ? error.response.data : error);
        return res.status(400).json({
          code: 400,
          message: '微信登录失败'
        });
      }
    }

    // 查找或创建用户
    let user = await prisma.user.findFirst({
      where: { phone }
    });

    const isNewUser = !user;

    if (!user) {
      // 创建新用户
      user = await prisma.user.create({
        data: {
          openId,
          phone,
          points: 0,
          memberType: 0
        }
      });

      console.log('Created new user:', user);

      // 如果有邀请人，建立分享关系并发放奖励
      if (inviter_id && scene) {
        await handleShareReward(inviter_id, user.id, scene);
      }
    } else {
      // 更新openId
      await prisma.user.update({
        where: { id: user.id },
        data: { openId }
      });
      console.log('Updated existing user:', user);
    }

    // 生成JWT token
    const token = jwt.sign(
      { userId: user.id },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES_IN }
    );

    console.log('Generated token for user:', user.id);

    res.json({
      code: 0,
      data: {
        token,
        is_new_user: isNewUser,
        user_info: {
          nickname: user.nickname,
          avatar: user.avatar,
          points: user.points,
          is_member: user.memberType > 0 && user.expireTime > new Date()
        }
      }
    });
  } catch (error) {
    console.error('Login error:', error);
    res.status(500).json({
      code: 500,
      message: '登录失败，请重试'
    });
  }
};

/**
 * 获取用户信息
 */
const getUserInfo = async (req, res) => {
  try {
    const user = await prisma.user.findUnique({
      where: { id: req.user.id }
    });

    if (!user) {
      return res.status(404).json({
        code: 404,
        message: '用户不存在'
      });
    }

    res.json({
      code: 0,
      data: {
        id: user.id,
        nickname: user.nickname,
        avatar: user.avatar,
        phone: user.phone,
        points: user.points,
        is_member: user.memberType > 0 && user.expireTime > new Date(),
        member_type: user.memberType,
        expire_time: user.expireTime
      }
    });
  } catch (error) {
    console.error('Get user info error:', error);
    res.status(500).json({
      code: 500,
      message: '获取用户信息失败'
    });
  }
};

/**
 * 更新用户信息
 */
const updateUserInfo = async (req, res) => {
  try {
    const { nickname, avatar } = req.body;
    
    await prisma.user.update({
      where: { id: req.user.id },
      data: {
        nickname,
        avatar
      }
    });

    res.json({
      code: 0,
      message: '更新成功'
    });
  } catch (error) {
    console.error('Update user info error:', error);
    res.status(500).json({
      code: 500,
      message: '更新用户信息失败'
    });
  }
};

const getPointsRecords = async (req, res) => {
  try {
    const { page = 1, size = 20 } = req.query;
    const skip = (page - 1) * size;

    const [total, records] = await Promise.all([
      prisma.pointsRecord.count({
        where: { userId: req.user.id }
      }),
      prisma.pointsRecord.findMany({
        where: { userId: req.user.id },
        orderBy: { createdAt: 'desc' },
        skip,
        take: size,
      })
    ]);

    res.json({
      code: 0,
      data: {
        total,
        list: records
      }
    });
  } catch (error) {
    console.error('Get points records error:', error);
    res.status(500).json({
      code: 500,
      message: 'Failed to get points records'
    });
  }
};

const getTodayPoints = async (req, res) => {
  try {
    const today = new Date();
    today.setHours(0, 0, 0, 0);

    const todayPoints = await prisma.pointsRecord.aggregate({
      where: {
        userId: req.user.id,
        createdAt: {
          gte: today
        },
        type: 1 // Points from exercise generation
      },
      _sum: {
        points: true
      }
    });

    const dailyLimit = 100;
    const earnedPoints = todayPoints._sum.points || 0;

    res.json({
      code: 0,
      data: {
        today_points: earnedPoints,
        remain_points: Math.max(0, dailyLimit - earnedPoints)
      }
    });
  } catch (error) {
    console.error('Get today points error:', error);
    res.status(500).json({
      code: 500,
      message: 'Failed to get today points'
    });
  }
};

async function handleInvitation(inviteeId, sharerId, scene) {
  try {
    // Create share record
    await prisma.shareRecord.create({
      data: {
        sharerId,
        inviteeId,
        scene,
        rewardDays: 7
      }
    });

    // Update both users' member expiry time
    const rewardDays = 7;
    const now = new Date();
    
    for (const userId of [sharerId, inviteeId]) {
      const user = await prisma.user.findUnique({
        where: { id: userId }
      });

      const newExpireTime = user.expireTime && user.expireTime > now
        ? new Date(user.expireTime.getTime() + rewardDays * 24 * 60 * 60 * 1000)
        : new Date(now.getTime() + rewardDays * 24 * 60 * 60 * 1000);

      await prisma.user.update({
        where: { id: userId },
        data: {
          memberType: 1,
          expireTime: newExpireTime
        }
      });
    }
  } catch (error) {
    console.error('Handle invitation error:', error);
    // Don't throw error to prevent blocking the registration process
  }
}

module.exports = {
  login,
  getUserInfo,
  updateUserInfo,
  getPointsRecords,
  getTodayPoints
}; 